package com.kaili.basic.service.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.kaili.basic.mapper.BaseMoveStoreMapper;
import com.kaili.basic.mapper.BaseOutStoreMapper;
import com.kaili.basic.pojo.dto.*;
import com.kaili.basic.pojo.entity.*;
import com.kaili.basic.pojo.vo.*;
import com.kaili.basic.service.*;
import com.kaili.common.exception.RestException;
import com.kaili.common.response.CommonStatus;
import com.kaili.common.response.RestStatus;
import com.kaili.common.util.LoginDetailUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional
public class BaseOutStoreServiceImpl extends ServiceImpl<BaseOutStoreMapper, BaseOutStoreEntity> implements BaseOutStoreService {

    @Autowired
    private BaseOutStoreDeatailService baseOutStoreDeatailService;

    @Autowired
    private BaseStoreStockService baseStoreStockService;

    @Autowired
    private BaseOutStoreMapper baseOutStoreMapper;

    @Autowired
    private BaseStoreAccountsService baseStoreAccountsService;

    @Autowired
    private OutboundApplicationService outboundApplicationService;

    @Override
    public RestStatus addOutStore(BaseOutStoreAddDTO dto) {
        //新增出库信息
        BaseOutStoreEntity entity=new BaseOutStoreEntity();
        BeanUtils.copyProperties(dto,entity);
        entity.setCreateBy(LoginDetailUtils.getCurrentEmployeeId().longValue());
        entity.setCreateTime(new Date());
        //统计数量
        for (BaseOutStoreDetailAddDTO detail:dto.getDetailList()) {
            entity.setTotalTrays(entity.getTotalTrays()+detail.getTrays());
            entity.setTotalVo(entity.getTotalVo()+detail.getVolume());
            entity.setTotalWeight(entity.getTotalWeight()+detail.getWeight());
            entity.setAmount(entity.getAmount()+detail.getAmount());
        }
        this.insert(entity);
        //新增出库明细信息
        baseOutStoreDeatailService.bathInsert(dto.getDetailList(),dto.getOrderNo());
        if(StringUtils.isNotBlank(dto.getLinkOrderNo())){
            //申请出库业务处理........
            outboundApplicationService.updateOrderOutbound(dto.getDetailList(),dto.getLinkOrderNo());
        }
        return CommonStatus.ADD_OK;
    }

    @Override
    public RestStatus updateOutStore(BaseOutStoreEditDTO editDto) {
        //插入移库记录
        BaseOutStoreEntity entity=new BaseOutStoreEntity();
        BeanUtils.copyProperties(editDto,entity);
        entity.setModifyTime(new Date());
        entity.setModifyBy(LoginDetailUtils.getCurrentEmployeeId().longValue());
        //统计数量
        for (BaseOutStoreDetailAddDTO detail:editDto.getDetailList()) {
            entity.setTotalTrays(entity.getTotalTrays()+detail.getTrays());
            entity.setTotalVo(entity.getTotalVo()+detail.getVolume());
            entity.setTotalWeight(entity.getTotalWeight()+detail.getWeight());
            entity.setAmount(entity.getAmount()+detail.getAmount());
        }
        //更新当前移库记录
        this.updateById(entity);
        //删除原有的产品明细
        baseOutStoreDeatailService.deleteByMap(new HashMap<String,Object>(){{put("order_no",editDto.getOrderNo());}});
        baseOutStoreDeatailService.bathInsert(editDto.getDetailList(),editDto.getOrderNo());
        return CommonStatus.UPDATE_OK;
    }

    @Override
    public RestStatus auditOutStore(BaseOutStoreAuditDto auditDto) throws RuntimeException{
        BaseOutStoreEntity entity = this.selectById(auditDto.getId());
        //已经做过审核不做处理
        if(!("0".equals(entity.getIsAuduit()))){
            return CommonStatus.UPDATE_OK;
        }
        //1.更改出库单为已审核
        entity.setIsAuduit(auditDto.getIsAudit());
        entity.setAuditBy(LoginDetailUtils.getCurrentEmployeeId().longValue());
        entity.setCreateTime(new Date());
        this.updateById(entity);

        //审核通过做正式出库操作
        List<BaseOutStoreDetailEntity> detailList = baseOutStoreDeatailService.selectByMap(new HashMap<String, Object>() {{
            put("order_no", auditDto.getOrderNo());
        }});

        //审核通过,修改出库申请可退货信息
        if("1".equals(auditDto.getIsAudit())){
            outboundApplicationService.updateOrderOutboundByAudit(detailList);
        }

        //2.更新原库存 如果存在库存不足则抛出异常
        Boolean flage = baseStoreStockService.updateStock(detailList);
        if(!flage){
            throw new RuntimeException();
        }

        //生成台账记录
        baseStoreAccountsService.insertBath(detailList);
        return CommonStatus.UPDATE_OK;
    }

    @Override
    public RestStatus updateOutStoreLogistics(BaseOutStoreLogisticsEditDto editDto) {
        BaseOutStoreEntity entity=new BaseOutStoreEntity();
        BeanUtils.copyProperties(editDto,entity);
        this.updateById(entity);
        return CommonStatus.UPDATE_OK;
    }

    @Override
    public Page<BaseOutStoreDetailVO> queryPageList(Page<BaseOutStoreDetailVO> page, BaseOutStoreQueryDto queryDto) {
        List<BaseOutStoreDetailVO> list=baseOutStoreMapper.queryPageList(page,queryDto);
        page.setRecords(list);
        return page;
    }

    @Override
    public List<BaseOutStoreDetailVO> queryDetailByOrderNo(HashMap<String, Object> orderNo) {
        return baseOutStoreMapper.queryDetailByOrderNo(orderNo);
    }

    @Override
    public BaseOutStoreDetailVO queryOutStoreDetail(HashMap<String, Object> map) {
        BaseOutStoreDetailVO detailVO = baseOutStoreMapper.queryPageList(map);
        List<BaseOutStoreDetailVO> list = baseOutStoreMapper.queryDetailByOrderNo(new HashMap<String, Object>() {{
            put("orderNo", detailVO.getOrderNo());
        }});
        detailVO.setList(list);
        return detailVO;
    }

    @Override
    public List<BaseOutStoreExportVO> outStoreExport(BaseOutStoreQueryDto queryDto) {
        return baseOutStoreMapper.outStoreExport(queryDto);
    }

    @Override
    public Long queryStoreOrderNo() {
        return baseOutStoreMapper.queryStoreOrderNo();
    }

    @Override
    public RestStatus addOutApply(BaseOutApplyAddDTO addDto)throws Exception {
        List<BaseOutStoreDetailAddDTO> destList=new ArrayList<>();
        List<BaseOutApplyDetailAddDTO> detailList = addDto.getDetailList();
        for (BaseOutApplyDetailAddDTO detail : detailList) {
            Map<String,Object> map=new HashMap<>();
            map.put("supplierId",addDto.getSupplierId());
            map.put("storeId",detail.getStoreId());
            map.put("productId",detail.getProductId());
            List<BaseStoreStockEntity> stockList = baseStoreStockService.queryStockBySupplierId(map);
            boolean flage = addOutStockByApply(destList, stockList, detail);
            if(!flage){
                throw new Exception();
            }
        }
        //补全信息
        BaseOutStoreAddDTO outStore=new BaseOutStoreAddDTO();
        BeanUtils.copyProperties(addDto,outStore);
        outStore.setOrderNo(String.valueOf(queryStoreOrderNo()));
        outStore.setDetailList(destList);
        return addOutStore(outStore);
    }

    public boolean addOutStockByApply(List<BaseOutStoreDetailAddDTO> destList,List<BaseStoreStockEntity> stockList,BaseOutApplyDetailAddDTO addDTO){
        Long totalAmount=0L;
        //1.如果现有库存一次够出完,直接出指定库存
        for (BaseStoreStockEntity detail : stockList) {
             if(detail.getCurrAmount()>=addDTO.getAmount()){
                 BaseOutStoreDetailAddDTO outStoreDetail=new BaseOutStoreDetailAddDTO();
                 BeanUtils.copyProperties(addDTO,outStoreDetail);
                 outStoreDetail.setStoreStockId(detail.getId());
                 outStoreDetail.setAmount(addDTO.getAmount());
                 destList.add(outStoreDetail);
                 return true;
             }
            totalAmount+=detail.getCurrAmount();
        }

        //2.所有库存总量低于要出库量无法出库
        if(totalAmount<addDTO.getAmount()){
            return false;
        }

        //3.所有库存总量够出，则进行匹配库存出货
        Long amount = addDTO.getAmount();
        for (int i = 0; i < stockList.size(); i++) {
            BaseStoreStockEntity entity = stockList.get(i);
            if(amount-entity.getCurrAmount()>0){
                amount-=entity.getCurrAmount();
                destList.add(addOutStock(entity.getCurrAmount(),entity,addDTO));
            }else if(amount-entity.getCurrAmount()==0){
                //已出全部库存
                destList.add(addOutStock(entity.getCurrAmount(),entity,addDTO));
                return true;
            }else{
                destList.add(addOutStock(amount,entity,addDTO));
            }
        }
        return true;
    }

    //根据出库申请生成出库明细
    public BaseOutStoreDetailAddDTO addOutStock(Long stockNum,BaseStoreStockEntity entity,BaseOutApplyDetailAddDTO addDTO){
        BaseOutStoreDetailAddDTO detail=new BaseOutStoreDetailAddDTO();
        detail.setAmount(stockNum);
        detail.setStoreStockId(entity.getId());
        detail.setTrays(0L);
        detail.setStoreStockId(addDTO.getApplyProductId());
        detail.setVolume(entity.getCurrVo()/entity.getCurrAmount()*stockNum);
        detail.setWeight(entity.getCurrVo()/entity.getCurrAmount()*stockNum);
        return detail;
    }
}
